package com.bobi.tfca.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bobi.tfca.dao.ActivityDao;
import com.bobi.tfca.model.entity.*;
import com.bobi.tfca.model.enums.ActivityStatusEnum;
import com.bobi.tfca.model.vo.ActivityVO;
import com.bobi.tfca.model.vo.MemberVO;
import com.bobi.tfca.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 活动服务层实现
 *
 * @author 李文发
 * @date 2024/4/3
 */
@Service
@Slf4j
public class ActivityServiceImpl extends ServiceImpl<ActivityDao, ActivityEntity> implements ActivityService {

    @Autowired
    private ActMemService actMemService;
    @Autowired
    private MemberService memberService;

    @Autowired
    private GroupService groupService;

    @Autowired
    private GroupMemberService groupMemberService;

    @Autowired
    private ActivityDao activityDao;

    @Override
    public List<ActivityVO> findAll(MemberEntity member) {
        List<ActivityVO> voList = new ArrayList<>();
        LambdaQueryWrapper<ActivityEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.notIn(ActivityEntity::getActivityStatus, List.of(ActivityStatusEnum.END.getCode(), ActivityStatusEnum.CANCELED.getCode()));
        queryWrapper.orderByDesc(ActivityEntity::getPublishTime);
        List<ActivityEntity> entityList = this.list(queryWrapper);
        if (entityList != null && entityList.size() > 0) {
            voList = entityList.stream().map(it -> {
                // 检查每个活动是否已经开始
                checkActivityStatus(it);
                // 转换为vo
                ActivityVO activityVO = ActivityEntity.ofActivityEntity(it);
                // 将vo内容等设置为空
                activityVO.setActivityDetails("");
                activityVO.setSignCondition("");
                // 获得角色
                if (member != null) {
                    ActMemEntity actMem = actMemService.getOne(new LambdaQueryWrapper<ActMemEntity>()
                            .eq(ActMemEntity::getMemberId, member.getMemberId())
                            .eq(ActMemEntity::getActivityId, it.getActivityId()));
                    String role = "";
                    if (actMem != null) {
                        role = actMem.getPrincipal() ? "负责人" : "成员";
                    } else {
                        role = "未报名";
                    }
                    activityVO.setRole(role);
                }
                return activityVO;
            }).toList();
        }

        return voList;
    }

    private void checkActivityStatus(ActivityEntity entity) {
        if (ActivityStatusEnum.NOT_START.getCode() == entity.getActivityStatus()) {
            LocalDateTime actStartTime = entity.getActStartTime();
            // 如果已经超过时间了，将数据库的状态设置为已经开始
            if (actStartTime.isBefore(LocalDateTime.now())) {
                entity.setActivityStatus(ActivityStatusEnum.STARTED.getCode());
                this.updateById(entity);
            }
        }
    }

    @Override
    public List<MemberVO> findAllMembers(Integer activityId) {
        List<MemberVO> memberVOList = new ArrayList<>();
        List<ActMemEntity> actMemEntities = actMemService.list(new LambdaQueryWrapper<ActMemEntity>().eq(ActMemEntity::getActivityId, activityId));
        if (actMemEntities != null && actMemEntities.size() > 0) {
            memberVOList = actMemEntities.stream().map(it -> {
                MemberEntity memberEntity = memberService.getById(it.getMemberId());
                MemberVO memberVO = MemberEntity.ofMemberEntity(memberEntity);
                // 设置角色
                String role = it.getPrincipal() ? "负责人" : "成员";
                memberVO.setRole(role);
                return memberVO;
            }).toList();
        }
        return memberVOList;
    }

    @Override
    public ActivityVO getActivityDetails(MemberEntity member, Integer activityId) {
        ActivityEntity activity = this.getById(activityId);
        // 获得角色
        ActMemEntity actMem = actMemService.getOne(new LambdaQueryWrapper<ActMemEntity>()
                .eq(ActMemEntity::getMemberId, member.getMemberId())
                .eq(ActMemEntity::getActivityId, activity.getActivityId()));
        String role = "";
        if (actMem != null) {
            role = actMem.getPrincipal() ? "负责人" : "会员";
        } else {
            role = "未报名";
        }
        ActivityVO activityVO = ActivityEntity.ofActivityEntity(activity);
        activityVO.setRole(role);
        // 设置活动状态
        activityVO.setActivityStatus(ActivityStatusEnum.getDescByCode(activity.getActivityStatus()));
        return activityVO;
    }

    @Override
    @Transactional
    public Integer organizeActivity(MemberEntity member, ActivityVO activityVO) {
        ActivityEntity activityEntity = ActivityVO.ofActivityVO(activityVO);
        activityEntity.setActivityId(null);
        // 设置时间
        activityEntity.setPublishTime(LocalDateTime.now());
        // 设置状态
        activityEntity.setActivityStatus(ActivityStatusEnum.NOT_START.getCode());
        activityEntity.setOrganizerId(member.getMemberId());
        activityEntity.setSignedNum(1);
        // 添加
        this.save(activityEntity);

        // 添加活动成员，自己
        ActMemEntity actMemEntity = new ActMemEntity();
        actMemEntity.setActivityId(activityEntity.getActivityId());
        actMemEntity.setMemberId(member.getMemberId());
        actMemEntity.setPrincipal(true);
        actMemService.save(actMemEntity);

        // 自动建群
        GroupEntity groupEntity = new GroupEntity();
        groupEntity.setGroupName(activityEntity.getActivityName());
        groupEntity.setGroupNum(1);
        groupEntity.setGroupHead(activityEntity.getOutsidePicture());
        groupEntity.setOwnerId(member.getMemberId());
        groupService.save(groupEntity);

        // 拉自己进群
        GroupMemberEntity groupMemberEntity = new GroupMemberEntity();
        groupMemberEntity.setGroupId(groupEntity.getGroupId());
        groupMemberEntity.setMemberId(member.getMemberId());
        groupMemberEntity.setGroupOwner(true);
        groupMemberService.save(groupMemberEntity);

        // 更新群id
        this.update(new LambdaUpdateWrapper<ActivityEntity>()
                .eq(ActivityEntity::getActivityId, activityEntity.getActivityId())
                .set(ActivityEntity::getGroupId, groupEntity.getGroupId()));

        return activityEntity.getActivityId();
    }

    @Override
    @Transactional
    public Boolean removeMember(Integer activityId, List<Integer> memberIds) {
        ActivityEntity entity = this.getById(activityId);
        if (!(ActivityStatusEnum.NOT_START.getCode().equals(entity.getActivityStatus())
                || ActivityStatusEnum.STARTED.getCode().equals(entity.getActivityStatus()))) {
            return false;
        }
        // 移除成员
        actMemService.remove(new LambdaQueryWrapper<ActMemEntity>()
                .eq(ActMemEntity::getActivityId, activityId)
                .in(ActMemEntity::getMemberId, memberIds));
        entity.setSignedNum(entity.getSignedNum() - memberIds.size());
        this.updateById(entity);

        // 移除群员
        groupMemberService.remove(new LambdaQueryWrapper<GroupMemberEntity>()
                .eq(GroupMemberEntity::getGroupId, entity.getGroupId())
                .in(GroupMemberEntity::getMemberId, memberIds));
        // 更新群人数
        groupService.incrementGroupNum(entity.getGroupId(), -memberIds.size());
        return true;
    }

    @Override
    @Transactional
    public Boolean cancelSign(MemberEntity member, Integer activityId) {
        ActivityEntity entity = this.getById(activityId);
        if (!ActivityStatusEnum.NOT_START.getCode().equals(entity.getActivityStatus())) {
            return false;
        }
        actMemService.remove(new LambdaQueryWrapper<ActMemEntity>()
                .eq(ActMemEntity::getActivityId, activityId)
                .eq(ActMemEntity::getMemberId, member.getMemberId()));
        entity.setSignedNum(entity.getSignedNum() - 1);
        this.updateById(entity);

        // 退群
        groupMemberService.remove(new LambdaQueryWrapper<GroupMemberEntity>()
                .eq(GroupMemberEntity::getGroupId, entity.getGroupId())
                .eq(GroupMemberEntity::getMemberId, member.getMemberId()));
        // 更新群人数
        groupService.incrementGroupNum(entity.getGroupId(), -1);
        return true;
    }

    @Override
    @Transactional
    public Integer signUp(MemberEntity member, Integer activityId) {
        ActivityEntity entity = this.getById(activityId);
        if (!ActivityStatusEnum.NOT_START.getCode().equals(entity.getActivityStatus())) {
            return 1;
        }
        // 查询是否已经报名，不能重复报名
        LambdaQueryWrapper<ActMemEntity> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(ActMemEntity::getActivityId, activityId)
                .eq(ActMemEntity::getMemberId, member.getMemberId());
        ActMemEntity one = actMemService.getOne(queryWrapper1);
        if (one != null) {
            return 2;
        }

        // 这里存在多线程并发问题，使用的是乐观锁CAS
        Boolean success = activityDao.signup(activityId);
        if (success) {
            ActMemEntity actMemEntity = new ActMemEntity();
            actMemEntity.setActivityId(activityId);
            actMemEntity.setMemberId(member.getMemberId());
            actMemEntity.setPrincipal(false);
            actMemService.save(actMemEntity);

            // 进群
            GroupMemberEntity groupMemberEntity = new GroupMemberEntity();
            groupMemberEntity.setGroupId(entity.getGroupId());
            groupMemberEntity.setMemberId(member.getMemberId());
            groupMemberEntity.setGroupOwner(false);
            groupMemberService.save(groupMemberEntity);

            // 更新群人数
            groupService.incrementGroupNum(entity.getGroupId(), 1);
            return 0;
        } else {
            return 3;
        }
    }

    @Override
    public Boolean finishActivity(Integer activityId) {
        ActivityEntity entity = this.getById(activityId);
        if (!ActivityStatusEnum.STARTED.getCode().equals(entity.getActivityStatus())) {
            return false;
        }
        LambdaUpdateWrapper<ActivityEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(ActivityEntity::getActivityStatus, ActivityStatusEnum.END.getCode())
                .eq(ActivityEntity::getActivityId, activityId);
        this.update(updateWrapper);
        return true;
    }

    @Override
    public Boolean cancelActivity(Integer activityId) {
        ActivityEntity entity = this.getById(activityId);
        if (ActivityStatusEnum.CANCELED.getCode().equals(entity.getActivityStatus()) || ActivityStatusEnum.END.getCode().equals(entity.getActivityStatus())) {
            return false;
        }
        LambdaUpdateWrapper<ActivityEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(ActivityEntity::getActivityStatus, ActivityStatusEnum.CANCELED.getCode())
                .eq(ActivityEntity::getActivityId, activityId);
        this.update(updateWrapper);
        return true;
    }

    @Override
    public List<ActivityVO> findMyActivities(MemberEntity member) {
        List<ActivityVO> voList = new ArrayList<>();
        // 查询参与的所有活动
        List<ActivityEntity> entityList = activityDao.selAllJoinActivities(member.getMemberId());
        if (entityList != null && entityList.size() > 0) {
            voList = entityList.stream().map(it -> {
                // 检查每个活动是否已经开始
                checkActivityStatus(it);
                // 转换为vo
                ActivityVO activityVO = ActivityEntity.ofActivityEntity(it);
                // 将vo内容等设置为空
                activityVO.setActivityDetails("");
                activityVO.setSignCondition("");
                // 获得角色
                ActMemEntity actMem = actMemService.getOne(new LambdaQueryWrapper<ActMemEntity>()
                        .eq(ActMemEntity::getMemberId, member.getMemberId())
                        .eq(ActMemEntity::getActivityId, it.getActivityId()));
                String role = "";
                if (actMem != null) {
                    role = actMem.getPrincipal() ? "负责人" : "成员";
                } else {
                    role = "未报名";
                }
                activityVO.setRole(role);
                return activityVO;
            }).toList();
        }
        return voList;
    }
}
